package com.cy.deepseeksport.NLP;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.BulkRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
import co.elastic.clients.elasticsearch.core.bulk.IndexOperation;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.json.JsonData;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cy.deepseeksport.aiService.SportsQueryAnalyzer;
import com.cy.deepseeksport.domain.ScheduleResult;
import com.cy.deepseeksport.mapper.ScheduleResultMapper;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@RestController
public class TeamNameSearch {


    @Resource
    private ScheduleResultMapper scheduleResultMapper;
    public static String indexName = "schedule_result";




    private OpenAiChatModel createChatModel() {
        return OpenAiChatModel.builder()
                .apiKey("26f9ab1f-3509-4f8e-b06e-7495bc93373a")
                .baseUrl("https://ark.cn-beijing.volces.com/api/v3/bots")
                .maxTokens(100)
                .modelName("bot-20250525124406-cqcw7")
                .build();
    }


    @GetMapping("/insertMatches")
    public String insertMatches(@RequestParam String prompt) throws IOException {
        QueryWrapper<ScheduleResult> queryWrapper = new QueryWrapper<>();
        //queryWrapper.apply("DATE(match_time) = DATE({0})", time);
        queryWrapper.select("match_id", "league_name_simplified", "home_team_name_simplified", "match_time", "away_team_name_simplified");
        List<ScheduleResult> scheduleResults = scheduleResultMapper.selectList(queryWrapper);
        List<BulkOperation> operations = new ArrayList<>();
        for (ScheduleResult scheduleResult : scheduleResults) {
            // 构建要存入 ES 的文档对象（用 Map 或定义 DTO 类）
            String leagueNameSimplified = scheduleResult.getLeagueNameSimplified();
            Map<String, Object> doc = new HashMap<>();
            doc.put("id", scheduleResult.getMatchId());
            doc.put("match_type", leagueNameSimplified); // 假设固定类型
            doc.put("info", scheduleResult.getHomeTeamNameSimplified() + ":" + scheduleResult.getAwayTeamNameSimplified());
            doc.put("match_time", scheduleResult.getMatchTime());

            // 添加到 Bulk 操作列表
            operations.add(BulkOperation.of(op -> op
                    .index(IndexOperation.of(i -> i
                            .index(indexName) // 替换为你的索引名
                            .id(scheduleResult.getMatchId().toString()) // 设置文档 ID

                            .document(doc)
                    ))
            ));
        }


        // 3. 执行批量插入
        if (!operations.isEmpty()) {
            BulkRequest bulkRequest = BulkRequest.of(b -> b.operations(operations));
            esClient.bulk(bulkRequest); // 同步执行
            // 异步方式：esClient.bulkAsync(bulkRequest, listener);
        }

        // 4. 可选：强制刷新索引使数据立即可查
        esClient.indices().refresh(r -> r.index(indexName));
        return "操作完成";
    }

    @GetMapping("/teamNameSearch")
    public String teamNameSearch(@RequestParam String prompt) throws IOException {

        SportsQueryAnalyzer analyzer = AiServices.create(SportsQueryAnalyzer.class, createChatModel());


        //String[] teamKeywords = null;
        MatchInfo matchInfo = analyzer.extractTeamInfo(prompt);


        String[] teamKeywords = matchInfo.teamNames;

        if (Objects.isNull(matchInfo.matchDate)) {

            SearchResponse<Map> response = esClient.search(s -> s
                            .index(indexName)
                            .query(q -> q
                                    .bool(b -> {
                                        //球队名称模糊检索
                                        b.must(m -> m
                                                .bool(bb -> {
                                                    for (String keyword : teamKeywords) {
                                                        String phrase;
                                                        if (keyword.endsWith("队")) {
                                                            phrase = keyword.substring(0, keyword.length() - 1).trim();
                                                        } else {
                                                            phrase = keyword;
                                                        }
                                                        bb.should(sh -> sh
                                                                .matchPhrase(mp -> mp
                                                                        .field("info")
                                                                        .query(phrase)
                                                                )
                                                        );

                                                    }
                                                    return bb;
                                                })
                                        );

                                        return b;
                                    })
                            )
                            .size(1),
                    Map.class
            );

            // 3. 处理结果
            List<Hit<Map>> hits = response.hits().hits();

            if (hits.isEmpty()) {
                log.info("没有找到比赛");
                return "没有找到比赛";
            }
            log.info("查询结果：{}", hits.get(0).source().get("info"));
            log.info("比赛id：{}", hits.get(0).source().get("id"));
            log.info("比赛时间：{}", hits.get(0).source().get("match_time"));
            log.info("数据可信度：{}", hits.get(0).score());

            return hits.get(0).source().toString();


        }
        Date matchDate = matchInfo.matchDate;

        String startDate = new SimpleDateFormat("yyyy-MM-dd").format(matchDate) + "T00:00:00.000Z";
        String endDate = new SimpleDateFormat("yyyy-MM-dd").format(matchDate) + "T23:59:59.999Z";


        SearchResponse<Map> response = esClient.search(s -> s
                        .index(indexName)
                        .postFilter(f -> f
                                .range(r -> r
                                        .field("match_time")  // 使用实际存储的字段名
                                        .gte(JsonData.of(startDate))
                                        .lte(JsonData.of(endDate))
                                ))
                        .query(q -> q
                                .bool(b -> {
                                     //球队名称模糊检索
                                    b.must(m -> m
                                            .bool(bb -> {
                                                for (String keyword : teamKeywords) {
                                                    String phrase;
                                                    if (keyword.endsWith("队")) {
                                                        phrase = keyword.substring(0, keyword.length() - 1).trim();
                                                    } else {
                                                        phrase = keyword;
                                                    }
                                                    bb.should(sh -> sh
                                                            .matchPhrase(mp -> mp
                                                                    .field("info")
                                                                    .query(phrase)
                                                            )
                                                    );

                                                }
                                                return bb;
                                            })
                                    );

                                    return b;
                                })
                        )
                        .size(1),
                Map.class
        );

        // 3. 处理结果
        List<Hit<Map>> hits = response.hits().hits();

        if (hits.isEmpty()) {
            log.info("没有找到比赛");
            return "没有找到比赛";
        }
        log.info("查询结果：{}", hits.get(0).source().get("info"));
        log.info("比赛id：{}", hits.get(0).source().get("id"));
        log.info("比赛时间：{}", hits.get(0).source().get("match_time"));
        log.info("数据可信度：{}", hits.get(0).score());

        return hits.get(0).source().toString();
    }



    @Resource
    private ElasticsearchClient esClient;

    @GetMapping("/createIndex")
    public String createIndex() throws IOException {

        // 索引名字
        String indexName = "schedule_result";

        // 索引是否存在
        BooleanResponse books = esClient.indices().exists(e -> e.index(indexName));
        System.out.println("索引是否存在：" + books.value());

        // 创建索引

        esClient.indices().create(c ->
                c.index(indexName)
                        .mappings(m -> m
                                .properties("id", p -> p.long_(l -> l))  // id 为 long 类型
                                .properties("match_type", p -> p.keyword(k -> k))  // match_type 为 keyword 类型
                                .properties("info", p -> p.text(t -> t  // info 使用 IK 中文分词
                                        .analyzer("ik_max_word")  // 最细粒度分词（适用于搜索）
                                        .searchAnalyzer("ik_smart")  // 智能分词（适用于查询）
                                        .fields("keyword", f -> f.keyword(k -> k))))  // 保留 keyword 子字段用于精确匹配
                                .properties("match_time", p -> p.date(d -> d  // match_time 为 date 类型
                                        .format("strict_date_optional_time||epoch_millis")))
                        )
                        .settings(s -> s  // 可选：自定义分词器设置
                                .analysis(a -> a
                                        .analyzer("ik_custom", ana -> ana  // 自定义 IK 配置（如果需要）
                                                .custom(cus -> cus
                                                        .tokenizer("ik_max_word")
                                                        .filter("lowercase")
                                                )
                                        )
                                )
                        )
        );

        // 删除索引
        //esClient.indices().delete(d -> d.index(indexName));
        return "操作完成";
    }

}
